package com.hwpt.hwaccount.feature.auth;

import android.content.Context;
import android.util.Log;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.hwpt.hwaccount.core.data.remote.RetrofitClient;
import com.hwpt.hwaccount.core.data.remote.api.ApiService;
import com.hwpt.hwaccount.core.data.remote.request.PwdLoginRequest;
import com.hwpt.hwaccount.core.data.remote.request.RegisterRequest;
import com.hwpt.hwaccount.core.data.remote.request.SendCodeRequest;
import com.hwpt.hwaccount.core.data.remote.request.VerifyCodeRequest;
import com.hwpt.hwaccount.core.data.remote.response.UserInfoResponse;

import com.hwpt.hwaccount.core.data.local.entity.UserEntity;
import com.hwpt.hwaccount.core.data.repository.UserInfoRepository;
import com.hwpt.hwaccount.core.utils.BeanUtils;
import com.hwpt.hwaccount.core.utils.JwtUtils;
import com.hwpt.hwaccount.feature.auth.utils.AuthValidator;
import com.hwpt.hwaccount.core.utils.NetworkResponseHandler;

public class AuthModel implements AuthContract.Model {
    private static final String TAG = "AuthModel";
    private final UserInfoRepository repository;
    private final Context context;
    private final ApiService apiService;

    public AuthModel(Context context) {
        this.context = context.getApplicationContext();
        this.repository = new UserInfoRepository(this.context);
        this.apiService = RetrofitClient.getApiService(this.context);
    }


    @Override
    public boolean validatePhone(String phone) {
        return AuthValidator.validatePhone(phone);
    }

    @Override
    public boolean validateAccount(String account) {
        return AuthValidator.validateAccount(account);
    }

    @Override
    public boolean validatePassword(String password) {
        return AuthValidator.validatePassword(password);
    }

    @Override
    public boolean validateVerifyCode(String verifyCode) {
        return AuthValidator.validateVerifyCode(verifyCode);
    }


    @Override
    public boolean validateRegister(String password, String confirmPassword) {
        return AuthValidator.validateRegister(password, confirmPassword);
    }

    //注册发送验证码
    @Override
    public void RegisterSendCode(String phone, AuthContract.Model.VerifyCodeCallback callback) {
        if (!validatePhone(phone)) {
            callback.onFailure(AuthValidator.getPhoneError(phone));
            return;
        }

        SendCodeRequest request = new SendCodeRequest(phone, "register");
        NetworkResponseHandler.handleSimpleResponse(
                apiService.sendVerifyCode(request),
                new NetworkResponseHandler.SimpleResponseCallback() {
                    @Override
                    public void onSuccess() {
                        callback.onSuccess(); // 只有成功时才回调成功
                    }

                    @Override
                    public void onFailure(String errorMsg) {
                        callback.onFailure(errorMsg); // 失败时回调失败
                    }
                }
        );
    }

    //注册校验验证码
    @Override
    public void RegisterVerifyCode(String phone, String verifyCode, AuthContract.Model.VerifyCodeCallback callback) {
        if (!validatePhone(phone)) {
            callback.onFailure(AuthValidator.getPhoneError(phone));
            return;
        }

        if (!validateVerifyCode(verifyCode)) {
            callback.onFailure(AuthValidator.getVerifyCodeError(verifyCode));
            return;
        }

        VerifyCodeRequest request = new VerifyCodeRequest(phone, verifyCode);

        NetworkResponseHandler.handleSimpleResponse(
                apiService.verifyCode(request),
                new NetworkResponseHandler.SimpleResponseCallback() {
                    @Override
                    public void onSuccess() {
                        callback.onSuccess();
                    }

                    @Override
                    public void onFailure(String errorMsg) {
                        callback.onFailure(errorMsg);
                    }
                }
        );
    }


    //注册
    @Override
    public void register(String phone, String password, String confirmPassword, AuthContract.Model.RegisterCallback callback) {
        if (!validatePhone(phone)) {
            callback.onFailure(AuthValidator.getPhoneError(phone));
            return;
        }

        if (!validateRegister(password, confirmPassword)) {
            callback.onFailure("两次密码不一致，请重新输入");
            return;
        }

        RegisterRequest request = new RegisterRequest(phone, password, confirmPassword);
        Log.d(TAG, "register: " + request.toString());
        NetworkResponseHandler.handleSimpleResponse(
                apiService.register(request),
                new NetworkResponseHandler.SimpleResponseCallback() {
                    @Override
                    public void onSuccess() {
                        callback.onSuccess("注册成功");
                    }

                    @Override
                    public void onFailure(String errorMsg) {
                        callback.onFailure(errorMsg);
                    }
                }
        );
    }


    //登录发送验证码
    @Override
    public void LoginSendCode(String phone, AuthContract.Model.VerifyCodeCallback callback) {
        if (!validatePhone(phone)) {
            callback.onFailure(AuthValidator.getPhoneError(phone));
            return;
        }

        SendCodeRequest request = new SendCodeRequest(phone, "login");
        NetworkResponseHandler.handleSimpleResponse(
                apiService.sendVerifyCode(request),
                new NetworkResponseHandler.SimpleResponseCallback() {
                    @Override
                    public void onSuccess() {
                        callback.onSuccess(); // 只有成功时才回调成功
                    }

                    @Override
                    public void onFailure(String errorMsg) {
                        callback.onFailure(errorMsg); // 失败时回调失败
                    }
                }
        );
    }

    //登录校验验证码
    @Override
    public void loginWithVerifyCode(String phone, String verifyCode, AuthContract.Model.VerifyCodeCallback callback) {
        if (!validatePhone(phone)) {
            callback.onFailure(AuthValidator.getPhoneError(phone));
            return;
        }

        if (!validateVerifyCode(verifyCode)) {
            callback.onFailure(AuthValidator.getVerifyCodeError(verifyCode));
            return;
        }

        VerifyCodeRequest request = new VerifyCodeRequest(phone, verifyCode);

        // 客户端调用
        NetworkResponseHandler.handleResponse(
                apiService.loginWithVerifyCode(request),
                new NetworkResponseHandler.ResponseCallback<UserInfoResponse>() {
                    @Override
                    public void onSuccess(UserInfoResponse userInfoResponse) {
                        Log.d(TAG, "onSuccess: " + userInfoResponse.toString());
                        if (userInfoResponse != null && userInfoResponse.getToken() != null &&
                                JwtUtils.validateToken(userInfoResponse.getToken())) {
                            saveUserToDatabase(userInfoResponse);
                            callback.onSuccess();
                        }
                    }

                    @Override
                    public void onFailure(String errorMsg) {
                        callback.onFailure(errorMsg);
                    }
                }
        );
    }


    //账密登录
    @Override
    public void loginWithPwd(String account, String password, AuthContract.Model.LoginCallback callback) {
        if (!validateAccount(account) || !validatePassword(password)) {
            callback.onFailure("账号或密码格式不正确");
            return;
        }

        PwdLoginRequest request = new PwdLoginRequest(account, password);
        NetworkResponseHandler.handleResponse(
                apiService.loginWithPwd(request),
                new NetworkResponseHandler.ResponseCallback<UserInfoResponse>() {
                    @Override
                    public void onSuccess(UserInfoResponse data) {
                        saveUserToDatabase(data);
                        callback.onSuccess("登录成功");
                    }

                    @Override
                    public void onFailure(String errorMsg) {
                        callback.onFailure(errorMsg);
                    }
                }
        );
    }


    /**
     * 将用户信息保存到Room数据库
     */
    private void saveUserToDatabase(UserInfoResponse userInfoResponse) {
        if (userInfoResponse == null) return;

        UserEntity userEntity = new UserEntity();
        BeanUtils.copyProperties(userInfoResponse, userEntity);


        repository.insertUser(userEntity)
                .subscribe(() -> {
                    Log.d(TAG, "用户信息保存成功");
                }, throwable -> {
                    Log.e(TAG, "用户信息保存失败", throwable);
                });
    }
}